#ifndef MYH264SAVER_H
#define MYH264SAVER_H

#include "CusH264Struct.h"
#include "Plugins/logHelper/cLoggerInterface.h"
#include "libVideoSaver/cVideoSaverBase.h"
#include "MyH264Vector.h"

#include <memory>
#include <list>
#include <mutex>
#include <deque>
#include <stdint.h>
#include <stdio.h>
#include <thread>
#include <condition_variable>

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

namespace libcvos_vfr
{

#define VIDEO_FRAME_LIST_SIZE 500

#define SAVING_FLAG_NOT_SAVE 0
#define SAVING_FLAG_SAVING 1
#define SAVING_FLAG_SHUT_DOWN 2

#define TIME_FLAG_UNDEFINE 0x7fffffff

	enum
	{
		type_unlimited,
		type_capture_clip
	};

	typedef struct _videoFileNode
	{
		std::string m_strFileName;
		uint64_t dw64BeginTimeTick;
		uint64_t dw64EndTimeTick;

		_videoFileNode(const char *fileName, uint64_t beginTime, uint64_t endTime, int frameRate) : m_strFileName(fileName),
																									dw64BeginTimeTick(beginTime),
																									dw64EndTimeTick(endTime)
		{
		}
	} videoFileNode;

	class MyH264Saver : public cLoggerInterface
	{
	public:
		MyH264Saver();
		~MyH264Saver();

		bool StartProcess(int iType = 0);

		int GetProcessMode();
		void SetProcessMode(int iValue);

		bool addDataStruct(CustH264Struct *pDataStruct);

		bool StartSaveH264_unlimited(uint64_t beginTimeStamp, const char *pchFilePath);
		bool StopSaveH264_unlimited(uint64_t TimeFlag = 0);

		bool SaveH264_CaptureClip(uint64_t beginTimeStamp, uint64_t endTimeStamp, const char *pchFilePath);

		int saveFrameListToVideo(std::deque<std::shared_ptr<CustH264Struct>> &frameList, const char *fileName);
		std::deque<std::shared_ptr<CustH264Struct>> getFrameListByTime(uint64_t beginTime, uint64_t endTime);

		void SetFileNameCallback(void *pUserData, void *pCallbackFunc);

		void SetIfExit(bool bValue);
		bool GetIfExit();

	private:
		void ProcessH264Data();

		uint32_t processH264Data_unlimited();
		uint32_t processH264Data_CaptureClip();

		void SendFileName(const char *fileName);

		void SetSaveFlag(int iValue);
		int GetSaveFlag();

		void SetStartTimeFlag(uint64_t iValue);
		uint64_t GetStartTimeFlag();

		void SetStopTimeFlag(uint64_t iValue);
		uint64_t GetStopTimeFlag();

		void SetIfFirstSave(bool bValue);
		bool GetIfFirstSave();

		void SetSavePath(const char *filePath, size_t bufLength);
		const char *GetSavePath();

		void WriteFormatLog(const char *szfmt, ...);

		void Init();
		void UnInit();

		void StartProcessThread();
		void StopProcessThread();
		void ClearData();

	private:
		bool m_bExit;
		bool m_bFirstSave;
		bool m_bWriteLog;
		int m_iSaveH264Flag; //   0--not save  ; 1--saving ; 2--shut down saving
		uint64_t m_iTimeFlag;
		uint64_t M_iStopTimeFlag;

		char m_chFilePath[256];
		char m_chCurrentPath[256];
		char *m_pLogBuf;

		uint64_t m_iTmpTime;
		int m_lastvideoidx;
		int m_iFrameLogID;
		int m_iVideoLogID;
		int m_iMode;

		void *m_pUserData;
		void *m_pCallbackFunc;

		std::deque<std::shared_ptr<CustH264Struct>> m_lDataStructList;
		MyH264DataVector m_lDataStructVector;

		std::list<std::shared_ptr<videoFileNode>> m_lVideoFileList;
		std::mutex m_txVideoFileList;

		std::mutex m_DataListLocker;
		std::mutex m_Locker;

		std::thread m_ThreadSaveH264;
		std::condition_variable m_conFile;

		cVideoSaverBase *m_hVideoSaver;

		std::mutex m_mtx;
	};

}

#endif // MYH264SAVER_H